Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

podman http api client #51

Merged
merged 34 commits into from
Nov 25, 2020
Merged

podman http api client #51

merged 34 commits into from
Nov 25, 2020

Conversation

towe75
Copy link
Collaborator

@towe75 towe75 commented Jul 20, 2020

See also #37

Goal

Goal of this PR is to replace the deprecated podman varlink api client with a http/rest based implementation.
It will not be a generic podman client, structs and methods will only implement the minimum needed attributes/features.

Todo

Client implementation

  • Automatically discover root and user-specific domain socket path
  • Configurable unix domain socket or http server path
  • Retry remote requests in case of network outages or known non-final responses

Endpoints

Port currently implemented varlink endpoints:

  • Create container
  • Force remove container
  • Container stats
  • System info
  • Inspect Container
  • Container Ps -> migrated to inspect api
  • REMOVE Pull image
  • Kill Container (port SignalTask Support, Add support for SignalTask. #64 )
  • Start Container
  • Stop Container

Buildsystem

  • ensure we can use the http api via github action runner

Port features

  • Ensure clean ENV in rootless mode (find alternative to older pull image approach)

Improvements

  • Improve GH Actions: run complete testsuite additionally in rootless mode
  • Stream Container Stats instead of polling

@mheon
Copy link

mheon commented Jul 31, 2020

Have you considered using the Golang API bindings in the Podman repo here?

@towe75
Copy link
Collaborator Author

towe75 commented Aug 1, 2020

@mheon , yes, we discussed about it in #37 and created also a podman issue at containers/podman#6866

We would like, of course, to reuse some of your work but hesitate to do it. Our concerns are:

  • huge dependency because the binding is not separated in a go module
  • somewhat unclear if this becomes the "official" client and is maintained for a longer time - hence podman issue 6866

Thank you for reaching out , it would be nice if you can clarify the intentions about your podman binding package.

Copy link
Contributor

@drewbailey drewbailey left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@towe75 this is amazing work! I have many stylistic nitpicks and only a few questions. Really awesome job getting this together. Let me know if you have any questions.

logger hclog.Logger
}

func NewClient(logger hclog.Logger) *APIClient {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GuessSocketPath sounds like we are guessing :) Thoughts on passing in a an Config struct, that contains a logger and socket path? when we initialize the config we can use a renamed version of GuessSocketPath as DefaultSocketPath is one isn't provided

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Method is now renamed to DefaultSocketPath().

Not sure how to approach the config struct. What about moving api initialization from NewPodmanDriver() to SetConfig()? This way we could simply share the drivers config with api or derive a separate struct from driverconfig.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO something like this would be nice, if SetConfig is the entry point it could be built up there, We can provide a DefaultConfig() method in the api package if we are initializing the client first, then calling setconfig but that seems like something to think about for future improvements to only call once

type ClientConfig struct{
         SocketPath string
}

func NewClient(cfg ClientConfig, logger hclog.Logger) *APIClient {

apiclient/apiclient.go Outdated Show resolved Hide resolved
func (c *APIClient) SetSocketPath(baseUrl string) {
c.logger.Debug("http baseurl", "url", baseUrl)
c.httpClient = &http.Client{
Timeout: 60 * time.Second,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Timeout seems like another good candidate to make configurable

apiclient/apiclient.go Outdated Show resolved Hide resolved
apiclient/container_inspect.go Outdated Show resolved Hide resolved
driver.go Outdated Show resolved Hide resolved
driver.go Outdated
} else if driverConfig.NetworkMode == "slirp4netns" {
createOpts.ContainerNetworkConfig.NetNS.NSMode = apiclient.Slirp
} else {
// FIXME: needs more work, parsing etc.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we track this with a github issue

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This "else" part is a typical place to handle not-yet-known requirements. I would not know what to write into the issue except "implement all possible podman network modes and switches". We can remove the FIXME because it's not a bug per se.

driver.go Show resolved Hide resolved
driver.go Show resolved Hide resolved
driver_test.go Outdated Show resolved Hide resolved
Copy link
Contributor

@drewbailey drewbailey left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

APL2 headers should be removed, repo is under MPL, no file specific headers necessary

apiclient/container_start.go Outdated Show resolved Hide resolved
renamed apiclient package to api
improved httpclient context usage
improved driver struct, renamed field podmanClient2 to podman
Renamed GuessSocketPath to DefaultSocketPath
Removed api-version constant
Cleaned up api-endpoints, do not use "compat" api, always send api version
Worked around flaky tests by adding sleeps to avoid very shortliving containers
Improved comments
Simplified TestPodmanDriver_SignalTask
api/container_delete.go Outdated Show resolved Hide resolved
api/container_create.go Outdated Show resolved Hide resolved
Moved all podman structs to new file structs.go
Moved api.NewClient to driver.SetConfig()
@towe75
Copy link
Collaborator Author

towe75 commented Nov 15, 2020

@drewbailey PTAL. Everything should be resolved now.

Copy link
Contributor

@drewbailey drewbailey left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking really good, just a few outstanding comments and questions left and then should be good to go!

if err != nil {
return response, err
}
// fmt.Println(string(jsonString))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// fmt.Println(string(jsonString))

}

// wait max 10 seconds for running state
timeout, cancel := context.WithTimeout(ctx, time.Second*10)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
timeout, cancel := context.WithTimeout(ctx, time.Second*10)
// TODO make timeout configurable
timeout, cancel := context.WithTimeout(ctx, time.Second*10)


var infoData Info

// the libpod/info endpoint seems to have some trouble
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// the libpod/info endpoint seems to have some trouble
// The libpod/info endpoint seems to have some trouble

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will remove this stale comment, we're not using the compat endpoint anymore.

driver.go Outdated
Comment on lines 2 to 5
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/

driver.go Outdated
@@ -341,6 +335,8 @@ func BuildContainerName(cfg *drivers.TaskConfig) string {

// StartTask creates and starts a new Container based on the given TaskConfig.
func (d *Driver) StartTask(cfg *drivers.TaskConfig) (*drivers.TaskHandle, *drivers.DriverNetwork, error) {
// d.logger.Warn("Env1", "env1", cfg.Env)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

re-bumping this :)

cgroupv2 := false
for _, l := range procFilesystems {
cgroupv2 = cgroupv2 || strings.HasSuffix(l, "cgroup2")
if cfg.Resources.NomadResources.Memory.MemoryMB > 0 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is this limit? MemoryMB * 1024 * 1024 seems high, unless memoryMB its bytes?

driver.go Outdated Show resolved Hide resolved
handle.go Outdated
Comment on lines 2 to 5
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/

main.go Outdated
Comment on lines 2 to 5
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/

state.go Outdated
Comment on lines 2 to 5
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/

@drewbailey drewbailey marked this pull request as ready for review November 25, 2020 18:17
@towe75 towe75 changed the title WIP podman http api client podman http api client Nov 25, 2020
@towe75 towe75 merged commit b580f2d into master Nov 25, 2020
@towe75 towe75 deleted the f-http-api branch November 25, 2020 18:21
@drewbailey drewbailey mentioned this pull request Dec 16, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants